package com.client.koshercook.client;

import java.util.ArrayList;
import java.util.List;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.i18n.client.HasDirection;
import com.google.gwt.i18n.client.HasDirection.Direction;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasAlignment;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.PushButton;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.VerticalPanel;

public class RecipeInfoPanel {

	public String link;
	private String myOriginal = "";
	private String myAlter = "";
	private List<String> lastIngs = new ArrayList<String>();
	private List<String> lastIngsPic = new ArrayList<String>();
	
	//dialog box for alternative name
	private DialogBox dBoxAlter = new DialogBox();
	private IngTextBox sBox = new IngTextBox();
	
	private final GreetingServiceAsync greetingService = GWT.create(GreetingService.class);
	
	//main panel
	private ScrollPanel mainSPanel;
	private DialogBox mainPanel = new DialogBox();
	private HTML recipeName = new HTML("שם המתכון כאן");
	private VerticalPanel Vpanel = new VerticalPanel();
	private VerticalPanel VpanelSubUp = new VerticalPanel();
	private HorizontalPanel HpanelUp = new HorizontalPanel();
	private HorizontalPanel HpanelDown = new HorizontalPanel();
	private HorizontalPanel HpanelSubUp = new HorizontalPanel();
	private PushButton close = new PushButton("סגור");
	private PushButton like = new PushButton("הוסף לספר המתכונים שלי");
	private SendMailBox sendMail = new SendMailBox();
	private int offsetWidht;
	private int offsetHeight;
	private int widhtLimit=950;
	private int HeightLimit=680;
	
	//instructions
	private VerticalPanel instructionsPanel = new VerticalPanel();
	private ScrollPanel instructionsScroller;
	private HTML instructionsText = new HTML("הוראות הכנה נכנסות כאן");
	private HTML instructionsHeader = new HTML("הוראות הכנה");
	
	//ingredients
	private VerticalPanel ingredientsPanel = new VerticalPanel();
	private ScrollPanel ingredientsScroller;
	private HTML ingredientsText = new HTML("מרכיבים נכנסים כאן");
	private HTML ingredientsHeader = new HTML("רכיבים");
	
	//ings table
	private ScrollPanel tableScroller;
	private VerticalPanel mainTable = new VerticalPanel();
	private HTML tableHeader = new HTML("משתמש ב"+":");
	private FlexTable table = new FlexTable();
	
	//rater
	private Rater rater = new Rater();
	
	//comments
	private HTML comments = new HTML("תגובות גולשים");
	private CommentBox addComment = new CommentBox();
	private boolean hasComment;
	//picture size
	private String picSize= "40px";

	//Cook Time
	private CookTime cookTime = new CookTime();

	/** constructor */
	public RecipeInfoPanel(){
		
		mainPanel.hide();
		mainPanel.setModal(false);
		mainPanel.setText("פרטי מתכון נבחר");
		
		recipeName.setStyleName("generalHeader");

		//create the instructions text box
		instructionsText.setDirection(HasDirection.Direction.RTL);
		
		instructionsScroller = new ScrollPanel(instructionsText);
		instructionsScroller.setSize("300px", "250px");
		instructionsScroller.addStyleName("infoText");
		
		instructionsHeader.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		instructionsHeader.addStyleName("infoTextHeader");
		
		instructionsPanel.add(instructionsHeader);
		instructionsPanel.add(instructionsScroller);
		instructionsPanel.addStyleName("instructionsPanel");
		
		//create the ingredients text box
		ingredientsText.setDirection(HasDirection.Direction.RTL);
	
		ingredientsScroller = new ScrollPanel(ingredientsText);
		
		ingredientsScroller.setSize("300px", "250px");
		ingredientsScroller.addStyleName("infoText");
		
		ingredientsHeader.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		ingredientsHeader.addStyleName("infoTextHeader");
		
		ingredientsPanel.add(ingredientsHeader);
		ingredientsPanel.add(ingredientsScroller);
		ingredientsPanel.addStyleName("ingredientsPanel");

		//create the table
		tableHeader.setDirection(HasDirection.Direction.RTL);
		tableHeader.addStyleName("infoTextHeader");
		table.setBorderWidth(1);
		table.setWidth("220px");
		table.getColumnFormatter().setWidth(0, "20px");
		table.getColumnFormatter().setWidth(2, picSize);
		tableScroller = new ScrollPanel(table);
		tableScroller.setSize("250px", "375px");
		mainTable.add(tableHeader);
		mainTable.add(tableScroller);
		
		//create the comments HTML
		comments.setDirection(HasDirection.Direction.RTL);
		
		close.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event) {
				Client.model.setInfoText("d");
				mainPanel.hide();
			}
		});
		
		like.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event) {
				if(!Client.model.isConnected()){
					Client.model.setInfoTextAndPO("עליך להיות מחובר בכדי להוסיף מתכון למועדפים");
				}else{
						greetingService.addUserFavorites(link, new AsyncCallback<Integer>(){
						public void onFailure(Throwable caught) {
							Client.model.setInfoTextAndPO("תקלה בהוספת מתכון למועדפים");
						}
						public void onSuccess(Integer result) {
							Client.model.setInfoTextAndPO("מתכון נקלט למועדפים");
						}
					});
				}
			}
		});
		
		//create the dialog box for alternative name
		Button ok = new Button("אישור");
		Button cancel = new Button("ביטול");

		sBox.getTextBox().addKeyUpHandler(new KeyUpHandler(){
			public void onKeyUp(KeyUpEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) {
					dBoxAlter.hide();
					sBox.setFocus(false);
				}
			}
		});
		
		ok.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event) {
				if(!Client.model.isConnected()){
					Client.model.setInfoTextAndPO("עליך להיות מחובר בכדי להזין שם חלופי לרכיבים");}
				else{
					//send the alter to the server
					myAlter = sBox.getText();
					if(!Client.model.serverKnowsIngName(myAlter)){
						sBox.setText("שם רכיב לא מוכר");
						return;
					}
					sBox.setText("");
					Client.model.addAlterToRecipe(link, myOriginal, myAlter);
					dBoxAlter.hide();
				}
			}
		});
		cancel.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event) {
				dBoxAlter.hide();
			}
		});
		DockPanel dp = new DockPanel();
		dp.setHorizontalAlignment(HasAlignment.ALIGN_RIGHT);
		dp.add(sBox, DockPanel.NORTH);
		dp.add(ok, DockPanel.EAST);
		dp.add(cancel, DockPanel.WEST);
		dBoxAlter.add(dp);
		dBoxAlter.setGlassEnabled(true);
		dBoxAlter.hide();
			
		//create the main info panel
		
		HpanelSubUp.add(instructionsPanel);
		HpanelSubUp.add(ingredientsPanel);
		HpanelSubUp.setSpacing(10);
		
		VpanelSubUp.add(HpanelSubUp);
		VpanelSubUp.add(cookTime);
		VpanelSubUp.setCellHorizontalAlignment(cookTime,  HasHorizontalAlignment.ALIGN_CENTER);

		HpanelUp.add(VpanelSubUp);
		HpanelUp.add(mainTable);
		HpanelUp.setSpacing(10);
		
		HpanelUp.addStyleName("bottomPanel");
		Vpanel.add(recipeName);
		Vpanel.add(HpanelUp);
		HpanelDown.add(close);
		HpanelDown.add(sendMail);
		HpanelDown.add(like);
		HpanelDown.add(addComment);
		HpanelDown.add(rater);
		HpanelDown.setSpacing(20);
		
		Vpanel.setSpacing(8);
		Vpanel.add(HpanelDown);
		Vpanel.add(comments);
		Vpanel.setCellHorizontalAlignment(comments, HasHorizontalAlignment.ALIGN_RIGHT);

		comments.setStyleName("comments");
		comments.setDirection(Direction.RTL);
		Vpanel.setStyleName("RecipeInfoPanel");
		
		mainSPanel = new ScrollPanel(Vpanel);
	
		mainPanel.add(mainSPanel);
		
	}
	
	
	/** set the recipe to view his instructions, ingredients, rater */
	public void setRecipe(final String link, final String recipeName){
		if(!mainPanel.isShowing())
			mainPanel.center();
		this.link = link;
		addComment.setLink(link);
		this.recipeName.setText(recipeName);
		instructionsText.setHTML("");
		ingredientsText.setHTML("");
		table.removeAllRows();
		cookTime.clearText();
		comments.setHTML("");
		disableButtons();
		Client.model.loader.center();
		greetingService.getRecipeInfo(link, new AsyncCallback<RecipeDetails>(){
			public void onFailure(Throwable caught) {
				instructionsText.setText("תקלה בקבלת המידע על המתכון");
				Client.model.loader.hide();
				close.setEnabled(true); //so we can close the window if error occurred 
			}
			public void onSuccess(RecipeDetails result) {
				enableButtons();
				instructionsText.setHTML(result.instructions);
				ingredientsText.setHTML(result.ingredients);
				rater.setRecipe(link, result.grade);
				cookTime.setRecipe(link, result.cookTime);
				updateTable(result.ings,result.ingsPic);
				//set the comments text:
				if(result.comments.size()==0){
					comments.setHTML("לא התקבלו תגובות גולשים");
					hasComment = false;
				}else{
					comments.setHTML("- תגובות גולשים -");
					for(String s : result.comments){
						int indx = s.indexOf("\u6000");
						String comment = s.substring(indx + 1);
						String uploader = s.substring(0, indx);
						addToCommentsDisplay(comment, uploader);
					}
					hasComment = true;
				}
				/*set the content of the send mail button if the recipe belongs to MatkonKasher
				else add the link */
				String content;
				if (link.startsWith("matkonkasher"))
					content = " http://matkonkasher.appspot.com/ ";
				else
					content = link;
				sendMail.setContent(content);
				sendMail.setSubject(recipeName);
				
				/* resize scroller is necessary */
				if (Vpanel.getOffsetHeight() < HeightLimit){
					offsetWidht = Vpanel.getOffsetWidth();
					offsetHeight = Vpanel.getOffsetHeight()+5;				
				}
				else{
					offsetWidht = widhtLimit;
					offsetHeight = HeightLimit;
				}
				
				mainSPanel.setSize(offsetWidht+"px" , offsetHeight+"px");
				Client.model.loader.hide();
			}
		});
	}
	
	/** updates the ings table of this recipe */
	private void updateTable(List<String> ings,List<String> ingsPic){
		lastIngs = ings;//not sure, maybe need to make a copy of ings here
		lastIngsPic = ingsPic;//not sure, maybe need to make a copy of ings here
		//clear the table
		table.removeAllRows();
		int indx = 0;
		//fill the table
		for(String s : ings){
			Image pic;
			table.getCellFormatter().setHorizontalAlignment(indx, 2, HasHorizontalAlignment.ALIGN_CENTER);
			table.setWidget(indx, 1, newAlterButton(link, s));
			if(Client.model.request.ingsContains(s))
				table.setWidget(indx, 0, new Image("check_1.gif"));
			else
				table.setWidget(indx, 0, new Image("check_0.gif"));
			if(ingsPic.get(indx).isEmpty())
				pic = new Image("no_picture.gif");
			else
				pic = new Image(ingsPic.get(indx));
			pic.setSize(picSize, picSize);
			table.setWidget(indx, 2, pic);
	
			indx++;
		}
		
	}
	
	/** use this when user adds more ingredients, but recipe is the same
	 *  (using ings list from last time) */
	public void updateTable(){
		if(lastIngs.size() > 0)	//if still have 
			updateTable(lastIngs,lastIngsPic);
		else
			return;
	}
	
	/** create a new button for suggesting an alter name */
	private Button newAlterButton(final String link, final String original){
		Button b = new Button(original);
		b.setTitle("לחץ להצעת רכיב חלופי");
		b.setWidth("100%");
		b.setHeight(picSize);
		b.setStyleName("empty");
		b.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event) {
				myOriginal = original;
				dBoxAlter.setText("הצע רכיב חלופי עבור "+original);
				dBoxAlter.center();
				sBox.setFocus(true);
			}
		});
		return b;
	}
	
	/** set smaller resolution */
	public void setSmaller(){
		instructionsScroller.setSize("180px", "150px");
		ingredientsScroller.setSize("180px", "150px");
		tableScroller.setSize("240px", "180px");
		mainSPanel.setSize("600px", "300px");
		picSize = "20px";
		widhtLimit = 600;
		HeightLimit = 300;
	}
	
	/** add one comment to the comment list */
	public void addToCommentsDisplay(String comment, String uploader){
		if (!hasComment){
			comments.setHTML("- תגובות גולשים -");
			hasComment = true;
		}
		comments.setHTML(comments.getHTML() + "<br />" + uploader + ": " + comment);
	}
	
	/** add one comment to the comment list and resize panel */
	public void addToCommentsDisplayWithRes(String comment, String uploader){
		if (!hasComment){
			comments.setHTML("- תגובות גולשים -");
			hasComment = true;
		}
		comments.setHTML(comments.getHTML() + "<br />" + uploader + ": " + comment);
		if (offsetHeight < HeightLimit){
			offsetHeight+=17;
		}
		else{
			offsetHeight = HeightLimit;
			offsetWidht = widhtLimit;
		}
			
		mainSPanel.setSize(offsetWidht+"px",offsetHeight+"px");
			
	}
	
	/** disable user feature buttons for non-register users */
	public void disableButtons(){
		rater.disable();
		cookTime.disable();
		close.setEnabled(false);
		like.setEnabled(false);
		sendMail.disable();
		addComment.disable();
	}
	
	/** enable user feature buttons for register users */
	public void enableButtons(){
		cookTime.enable();
		close.setEnabled(true);
		like.setEnabled(true);
		sendMail.enable();
		addComment.enable();
	}
}
